﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CRFSharp;
using System.IO;

namespace CRFSharp_Console
{
    class Program
    {
        static void Run(string strModelFileName, string strFileName)
        {
            if (File.Exists(strFileName) == false || File.Exists(strModelFileName) == false)
            {
                Console.WriteLine("FAILED: open {0} or {1} file failed.", strFileName, strModelFileName);
                return;
            }

            CRF_t crf_t = new CRF_t();
            CrfModel crf_model = new CrfModel();
            crf_out_t crf_out;
            crf_out = crf_t.crf_create_out(256);

            int ret;
            ret = crf_t.crf_load_model(ref crf_model, strModelFileName);
            if (ret < 0)
            {
                return;
            }

            SegCrfTag crf_tag = new SegCrfTag();
            crf_tag.seg_init_by_model(ref crf_model);

            List<List<string>> inbuf;
            inbuf = new List<List<string>>();

            StreamReader sr = new StreamReader(strFileName);
            while (sr.EndOfStream == false)
            {
                string strLine = sr.ReadLine().Trim();

                if (strLine.Length > 0)
                {
                    string[] items = strLine.Split(new char[] { '\t' });
                    inbuf.Add(new List<string>());
                    foreach (string item in items)
                    {
                        inbuf[inbuf.Count - 1].Add(item);
                    }
                }
                else
                {
                    Predict(crf_t, ref crf_out, ref ret, ref crf_tag, ref inbuf);
                    inbuf = new List<List<string>>();
                }
            }

            if (inbuf.Count > 0)
            {
                Predict(crf_t, ref crf_out, ref ret, ref crf_tag, ref inbuf);
            }

            sr.Close();
        }

        private static void Predict(CRF_t crf_t, ref crf_out_t crf_out, ref int ret, ref SegCrfTag crf_tag, ref List<List<string>> inbuf)
        {
            ret = crf_t.crf_segment_words(ref crf_tag, ref crf_out, ref inbuf, 1, 0);

            string strText = "";
            foreach (List<string> item in inbuf)
            {
                strText += item[0];
            }

            for (int i = 0; i < crf_out.nbest; i++)
            {
                string strout = "";
                foreach (crf_term_out_t item in crf_out.term_buf)
                {
                    for (int j = 0; j < item.crftermcount; j++)
                    {
                        string str = strText.Substring(item.crftermoffsets[j], item.crftermlen[j]);
                        string strNE = item.crfneprop[j].strTag;

                        if (strNE.Length > 0)
                        {
                            strout += str + "[" + strNE + "] ";
                        }
                        else
                        {
                            strout += str + " ";
                        }
                    }
                }

                Console.WriteLine(strout);
            }
        }

        static void Main(string[] args)
        {
            Run("ner.model.txt", "ne.test.txt");

            Console.ReadLine();
        }
    }
}
